require 'rubygems'
require 'serialport'

RAILS_ROOT = "/home/sfmonitor/sfmonitor/" if not defined? RAILS_ROOT

class TrendPointPoller

  @connections = []

  def initialize
    @connections, needed = check_for_ports(Trendpoint.count) 
    needed.each do |p| 
      c = initialize_node(p)
      @connections << c if c != nil
    end
  end

  def check_for_ports(ports)
    connections = []
    needed_ports = []
    Trendpoint.find(:all).each do |trendpoint| 
      conn = verify_node(trendpoint.id)
      if conn != nil
        connections << conn
      else
        needed_ports << trendpoint
      end
    end
    [connections, needed_ports]
  end

  def initialize_node trendpoint
    #puts "Node #{id}, (#{@@nodes[id]}) not connected, reinitializing connection."
    if Trendpoint.find(trendpoint.id) != nil
      cmd = "/usr/bin/dgrp/config/dgrp_cfg_node init  -v -v -e never #{trendpoint.id} #{trendpoint.address} 1"
      IO.popen(cmd) { |f| puts f.read }
      sleep 1.0
    end
    verify_node(id)
  end

  def connect_to_node(id)
    begin
      sp = SerialPort.new("/dev/tty_dgrp_#{id}_0", 115200)
      puts "Connected to #{@@nodes[id]}."
    rescue
      nil
    end
    sp
  end

  def verify_node(id)
    if Dir.entries("/dev").grep(/tty_dgrp_#{id}_0/).length > 0
      #puts "Successfully established connection to #{@@nodes[id]} @ tty_dgrp_#{id}_0."
      "tty_dgrp_#{id}_0"
    else
      nil
    end
  end

  def poll(port, start_address, num_registers)
    values = {}
    data = ""
    cmd = "#{RAILS_ROOT}/app/controllers/modpoll -r #{start_address} -c #{num_registers} -b 115200 -p none -t 3 -1 -o 10.0 /dev/#{port}"

    IO.popen(cmd) { |f| data = f.read }
    data.split("\n").each do |line|
      if line.index(":") != nil and line.index("[") != nil
        reg_no = line.split(":")[0].delete("[").delete("]").strip.to_i
        val = line.split(":")[1].strip.to_i
        values[reg_no] = val
      end
    end
    values
  end

  def poll_single_register(port, address)
    hash_values = poll(port, address, 1)
    hash_values[hash_values.keys[0]]
  end

  def get_watt_values
    @connections.each do | port |
      (1..88).each do |ct|
        watts = poll_single_register(port, ((ct * 10) + 16))
        puts "#{@@nodes[port.split("_")[2].to_i]}, CT\##{ct}: #{watts} watts"
      end
    end
  end

  def get_watt_values_fast
    value_pairs = []
    @connections.each do | port |
      value_hash = {}
      (0..8).each { |i| value_hash.merge!(poll(port, 11 + (100 *i), 100)) }
      (16..886).step(10) do |reg_no|
        value_pairs<<["#{@@nodes[port.split("_")[2].to_i].split(".")[3]}-CT#{(reg_no-6)/10}", value_hash[reg_no].to_i] if value_hash[reg_no] != 0
      end
    end
    value_pairs
  end

  def poll_hosts
    get_watt_values_fast
  end

end
